﻿using System;
using System.Management;
using System.Collections.Generic;
using System.Windows;

namespace eipch
{
    class NetworkManagement
    {

        private ManagementClass _objMC;
        private ManagementObjectCollection _objMOC;

        public NetworkManagement()
        {
            _objMC = new ManagementClass("Win32_NetworkAdapterConfiguration");
            _objMOC = _objMC.GetInstances();
        }

        /// <summary>
        /// Update configurations
        /// </summary>
        public void reload()
        {
            _objMOC.Dispose();
            _objMC.Dispose();

            _objMC = new ManagementClass("Win32_NetworkAdapterConfiguration");
            _objMOC = _objMC.GetInstances();
        }

        /// <summary>
        /// Returns a List<String> with adapter names
        /// </summary>
        /// <returns></returns>
        public List<String> getListOfNIC()
        {

            this.reload();

            List<String> nics = new List<string>();

            foreach (ManagementObject objMO in _objMOC)
            {
                if ((bool)objMO["IPEnabled"] && !(objMO["Caption"].ToString().Contains("VMware")))
                {
                    nics.Add(objMO["Caption"].ToString());
                }
            }

            return nics;
        }

        /// <summary>
        /// Read the current network config
        /// </summary>
        /// <param name="NICName">Adapter name</param>
        /// <returns></returns>
        public NetworkConfiguration getCurrentConfiguration(String NICName)
        {
            this.reload();

            NetworkConfiguration networkConfig = new NetworkConfiguration();

            foreach (ManagementObject objMO in _objMOC)
            {
                if ((bool)objMO["IPEnabled"])
                {
                    if (objMO["Caption"].Equals(NICName))
                    {
                        try
                        {
                            networkConfig.ipAddress = new IPAddress(((String[])objMO["IPAddress"])[0]);
                            networkConfig.netMask = new IPAddress(((String[])objMO["IPSubnet"])[0]);
                            networkConfig.gateway = new IPAddress(((String[])objMO["DefaultIPGateway"])[0]);
                            networkConfig.dns = IPAddress.generateIPAddressList((String[])objMO["DNSServerSearchOrder"]);
                            networkConfig.dhcp = (Boolean)objMO["DHCPEnabled"];
                            networkConfig.mac = (String)objMO["MACAddress"];
                            networkConfig.isSet = true;
                        }
                        catch (NullReferenceException)
                        {
                            MessageBox.Show("Fehler beim aktualisieren der Parameter", "Fehler");
                        }
                    }
                }
            }

            return networkConfig;
        }

        public void setNewConfiguration(String NICName, NetworkConfiguration newNetworkConfig)
        {
            foreach (ManagementObject objMO in _objMOC)
            {
                if ((bool)objMO["IPEnabled"])
                {
                    if (objMO["Caption"].Equals(NICName))
                    {
                        try
                        {
                            if (newNetworkConfig.dhcp)
                            {

                                ManagementBaseObject newDNS = objMO.GetMethodParameters("SetDNSServerSearchOrder");
                                ManagementBaseObject newGate = objMO.GetMethodParameters("SetGateways");

                                newDNS["DNSServerSearchOrder"] = new String[] { };
                                newGate["DefaultIPGateway"] = null;
                                newGate["GatewayCostMetric"] = new int[] { 1 };

                                objMO.InvokeMethod("EnableDHCP", null);
                                objMO.InvokeMethod("SetDNSServerSearchOrder", newDNS, null);
                                objMO.InvokeMethod("SetGateways", newGate, null);

                                objMO.InvokeMethod("RenewDHCPLease", null);
                            }
                            else
                            {
                                ManagementBaseObject newIP = objMO.GetMethodParameters("EnableStatic");
                                ManagementBaseObject newGate = objMO.GetMethodParameters("SetGateways");
                                ManagementBaseObject newDNS = objMO.GetMethodParameters("SetDNSServerSearchOrder");

                                newGate["DefaultIPGateway"] = new string[] { newNetworkConfig.gateway.ToString() };
                                newGate["GatewayCostMetric"] = new int[] { 1 };

                                newIP["IPAddress"] = new string[] { newNetworkConfig.ipAddress.ToString() };
                                newIP["SubnetMask"] = new string[] { newNetworkConfig.netMask.ToString() };

                                newDNS["DNSServerSearchOrder"] = newNetworkConfig.dns.ToArray();

                                objMO.InvokeMethod("EnableStatic", newIP, null);
                                objMO.InvokeMethod("SetGateways", newGate, null);
                                objMO.InvokeMethod("SetDNSServerSearchOrder", newDNS, null);
                            }
                        }
                        catch (Exception e)
                        {
                            MessageBox.Show("Es ist ein Fehler aufgetreten. Bitte erneut versuchen. \nFehler: " + e.Message, "Neue Einstellungen setzen");
                        }

                    }
                }
            }


        }

        public void DHCP_release(String NICName)
        {


            foreach (ManagementObject objMO in _objMOC)
            {
                if ((bool)objMO["IPEnabled"])
                {
                    if (objMO["Caption"].Equals(NICName))
                    {
                        try
                        {
                            objMO.InvokeMethod("ReleaseDHCPLease", null);
                        }
                        catch (Exception e)
                        {
                            MessageBox.Show("Es ist ein Fehler aufgetreten. Bitte erneut versuchen. \nFehler: " + e.Message, "DHCP Release");
                        }
                    }
                }
            }

        }

        public void DHCP_renew(String NICName)
        {

            foreach (ManagementObject objMO in _objMOC)
            {
                if ((bool)objMO["IPEnabled"])
                {
                    if (objMO["Caption"].Equals(NICName))
                    {
                        try
                        {
                            objMO.InvokeMethod("RenewDHCPLease", null);
                        }
                        catch (Exception e)
                        {
                            MessageBox.Show("Es ist ein Fehler aufgetreten. Bitte erneut versuchen. \nFehler: " + e.Message, "DHCP renew");
                        }
                    }
                }
            }
        }
    }
}
